Superscalar processors employ aggressive techniques to exploit instruction-level parallelism. Wide dispatch and issue paths place an upper bound on peak instruction throughput. Large issue buffers are used to maintain a window of instructions necessary for detecting parallelism, and a large pool of physical registers provides destinations for all of the in-flight instructions issued from the window beyond the dispatch boundary. To enable concurrent execution of instructions, the execution engine is composed of many parallel functional units. The fetch engine speculates past multiple branches in order to supply a continuous instruction stream to the decode, dispatch, and execution pipelines in order to maintain a large window of potentially executable instructions.
The trend in superscalar design is to scale these techniques: wider dispatch/issue, larger windows, more physical registers, more functional units, and deeper speculation. To maintain this trend, it is important to balance all parts of the processor-any bottlenecks diminish the benefit of aggressive techniques.
Instruction fetch performance depends on a number of factors. Instruction cache hit rate and branch prediction accuracy have been long recognized as important problems in fetch performance and are well-researched areas.
Modern microprocessors routinely use a plurality of mechanisms to improve their ability to efficiently fetch past branch instructions. These prediction mechanisms allow a processor to fetch beyond a branch instruction before the outcome of the branch is known. For example, some mechanisms allow a processor to speculatively fetch beyond a branch before the branch's target address has been computed. These techniques use run-time history to speculatively predict which instructions should be fetched and eliminate "dead" cycles that might normally be wasted. Even with these techniques, current microprocessors are limited in fetching instructions during a clock cycle. As superscalar processors become more aggressive and attempt to execute many more instructions per cycle, they must also be able to fetch many more instructions per cycle.
High performance superscalar processor organizations divide naturally into an instruction fetch mechanism and an instruction execution mechanism. The fetch and execution mechanisms are separated by instruction issue buffer(s), for example, queues, and reservation stations, etc. Conceptually, the instruction fetch mechanism acts as a "producer" which fetches, decodes, and places instructions into a reorder buffer. The instruction execution engine "prepares" instructions for completions. The completion engine is the "consumer" which removes instructions from the buffer and executes them, subject to data dependence and resource constraints. Control dependencies (branches and jumps) provide a feedback mechanism between the producer and consumer.
As instruction fetch decode and dispatch pipelines become wider, it becomes important to optimize the translation from the complex instruction set with a large amount of implicit information to an explicit instruction set that does not require the use of architected registers. This is particularly true in situations where the internal instructions do not have a direct one to one relationship to the external instructions. This is typically done to facilitate faster cycle times, simplify design or reduce the execution and/or register resources required for that instruction's execution. This uneven expansion of instructions as they flow down the pipeline have the side effect of making it extremely difficult to track and correlate instructions in the fetch unit and the decode unit after they have been expanded.
As processors are optimized for higher frequency operation they are being implemented with more pipeline stages. This along with a requirement for more accurate branch and fetch prediction forces increased instructions to be passed further down the processor pipeline before fetch predictors or branch predictors can be resolved.
Speculative branch prediction requires that each branch instruction is denoted by some unique value or enumeration to allow canceling out instructions which were fetched, passed down the pipeline and then determined not to be from the proper instruction stream. Some processor architectures distinguish different branch types from one another, in this case multiple "branch tags" would be required.
Accordingly, what is needed is a mechanism for forming independently generated identifying branch tags in multiple units which can be used to track, flush, and cancel fetch groups and portions of fetch groups upon resolution of the fetch and branch predictors. The present invention addresses such a need.